<?php

namespace App\Kuafu\Pay\Service;

use App\Kuafu\Activity\Enum\ActivityEnum;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\CouponExt\Channel\CouponExtBase;
use App\Kuafu\CouponExt\Enum\CouponExtCodeEnum;
use App\Kuafu\CouponExt\Enum\CouponExtEnum;
use App\Kuafu\CouponExt\Exceptions\CouponExtException;
use App\Kuafu\CouponExt\Model\OrderCouponExtSplitModel;
use App\Kuafu\CouponPackage\Model\CouponPackageModel;
use App\Kuafu\CouponPackage\Model\CouponPackageOrderModel;
use App\Kuafu\CustomerCoupon\Exceptions\CustomerCouponException;
use App\Kuafu\CustomerCoupon\Service\CustomerCouponService;
use App\Kuafu\CustomPayment\Enum\CustomPaymentEnum;
use App\Kuafu\Order\Enum\CodeEnum;
use App\Kuafu\Order\Exceptions\OrderException;
use App\Kuafu\Order\Service\OrderPay;
use App\Kuafu\Pay\BasePay;
use App\Kuafu\Pay\Enum\BasePayEnum;
use App\Kuafu\Pay\Enum\FuYouPayEnum;
use App\Kuafu\Pay\Enum\PayCodeEnum;
use App\Kuafu\Pay\Exceptions\PayException;
use App\Kuafu\Pay\Jobs\PayPolling;
use App\Kuafu\Pay\Jobs\PayRefundCallback;
use App\Kuafu\Pay\Jobs\RefundPolling;
use App\Kuafu\Pay\Model\PayCallbackLog;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Model\RefundStreamModel;
use App\Library\FeiShu\SendFs;
use App\Library\SnowFlake\SnowFlake;
use GuzzleHttp\Client;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 查询PayStream列表的类
 */
class PayListsService
{
    private array $payNos;
    private array $orderIds;
    private array $sysTypes;
    private int   $startTime;
    private int   $endTime;
    private int   $pageSize;
    private int   $pageNum;
    private array $field;

    /**
     * @param array $field
     */
    public function setField(array $field): self
    {
        $this->field = $field;
        return $this;
    }

    /**
     * @param array $payNos
     */
    public function setPayNos(array $payNos): self
    {
        $this->payNos = $payNos;
        return $this;
    }

    /**
     * @param array $orderIds
     * @return $this
     */
    public function setOrderIds(array $orderIds): self
    {
        $this->orderIds = $orderIds;
        return $this;
    }

    /**
     * @param int $sysTypes
     * @return $this
     */
    public function setSysTypes(array $sysTypes): self
    {
        $this->sysTypes = $sysTypes;
        return $this;
    }

    /**
     * @param string $startTime
     * @return $this
     */
    public function setStartTime(string $startTime): self
    {
        $this->startTime = $startTime;
        return $this;
    }

    /**
     * @param string $endTime
     * @return $this
     */
    public function setEndTime(string $endTime): self
    {
        $this->endTime = $endTime;
        return $this;
    }

    /**
     * @param int $pageSize
     * @return $this
     */
    public function setPageSize(int $pageSize): self
    {
        $this->pageSize = $pageSize;
        return $this;
    }

    /**
     * @param int $pageNum
     * @return $this
     */
    public function setPageNum(int $pageNum): self
    {
        $this->pageNum = $pageNum;
        return $this;
    }

    /**
     * 校验参数入口
     * @return bool
     * @throws PayException
     */
    private function checkParam(): bool
    {
        if ($this->orderIds) {
            return $this->checkByOrderIds();
        }

        if ($this->startTime || $this->endTime) {
            return $this->checkByStartEndTime();
        }

        if ($this->payNos) {
            return $this->checkPayNos();
        }

        throw new PayException(PayCodeEnum::ERR_PAY_LISTS_PARAM);
    }

    /**
     * 校验参数 - 通过orderIds
     * @return bool
     * @throws PayException
     */
    private function checkByOrderIds(): bool
    {
        if (count($this->orderIds) > 200) {
            throw new PayException(PayCodeEnum::ERR_PAY_LISTS_PARAM, 'orderIds不能超过200个');
        }

        return true;
    }

    /**
     * 校验参数 - 通过payNos
     * @return bool
     * @throws PayException
     */
    private function checkPayNos(): bool
    {
        if (count($this->payNos) > 200) {
            throw new PayException(PayCodeEnum::ERR_PAY_LISTS_PARAM, 'orderIds不能超过200个');
        }

        return true;
    }

    /**
     * 校验参数 - 通过时间范围
     * @return bool
     * @throws PayException
     */
    private function checkByStartEndTime(): bool
    {
        if ($this->pageSize > 200) {
            throw new PayException(PayCodeEnum::ERR_PAY_LISTS_PARAM, 'pageSize不能超过200');
        }

        return true;
    }

    /**
     * payStream列表
     * @return array
     * @throws PayException
     */
    public function payStreamLists(): array
    {
        // 校验参数
        $this->checkParam();

        // 现阶段业务 - 订货对账文件、开店对账。均不涉及富有

        $query = PayStreamModel::suffix(null)
                               ->when($this->payNos, function ($query) {
                                   $query->whereIn('payNo', $this->payNos);
                               })
                               ->when($this->orderIds, function ($query) {
                                   $query->whereIn('orderId', $this->orderIds);
                               })
                               ->when($this->sysTypes, function ($query) {
                                   $query->whereIn('sysType', $this->sysTypes);
                               })
                               ->when($this->startTime, function ($query) {
                                   $query->where('createdAt', '>=', $this->startTime);
                               })
                               ->when($this->endTime, function ($query) {
                                   $query->where('createdAt', '<=', $this->endTime);
                               })
                               ->where('payStatus', PayStreamModel::PAY_STATUS_1);

        if ($this->pageSize) {
            $count   = $query->count();
            $hasMore = ($this->pageSize * $this->pageNum) < $count;
        } else {
            $hasMore = false;
        }

        $lists = $query
            ->when($this->pageSize && $this->pageNum, function ($query) {
                $query->forPage($this->pageNum, $this->pageSize);
            })
            ->select($this->field)
            ->get()
            ->map(function ($item) {
                $item['payChannelText'] = $item->payChannelName;
                return $item;
            });

        return ['hasMore' => $hasMore, 'lists' => $lists];
    }
}
